package com.topscomm.mis.cbb.file.compare.word.handler.impl;

import com.topscomm.mis.cbb.file.compare.cj.CjSystemConst;
import com.topscomm.mis.cbb.file.compare.cj.pojo.CjCompareJobResultEntity;
import com.topscomm.mis.cbb.file.compare.cj.pojo.dto.CompareItemsDto;
import com.topscomm.mis.cbb.file.compare.cj.pojo.dto.CompareTableStyleDto;
import com.topscomm.mis.cbb.file.compare.word.handler.BasicCompareHandler;
import com.topscomm.mis.cbb.file.compare.word.handler.IParagraphCompareHandler;
import com.topscomm.mis.cbb.file.compare.word.handler.ITableCompareHandler;
import com.topscomm.mis.cbb.file.compare.word.util.PoiWordUtil;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @description:
 * @author: zhanglongfei
 * @date: 2023/2/21 18:39
 */
@Component
public class DefaultTableCompareHandler extends BasicCompareHandler implements
    ITableCompareHandler {

    @Autowired(required = false)
    private List<IParagraphCompareHandler> paragraphCompareHandlers;

    /**
     * @param table1:
     * @param table2:
     * @param compareItemsDto: 2023-06-14 wxm添加参数：支持对比项自定义
     * @description: 比对两个表格差异，返回差异明细
     * @return: java.util.List<com.topscomm.mis.cbb.file.compare.cj.pojo.CjCompareJobResultEntity>
     * @author: zhanglongfei
     * @date: 2023/2/21 13:46
     * @modify:
     */
    @Override
    public List<CjCompareJobResultEntity> doCompare(XWPFTable table1, XWPFTable table2,
        CompareItemsDto compareItemsDto) {
        List<CjCompareJobResultEntity> resultList = new ArrayList<>();
        int tableNo = PoiWordUtil.getTablePos((XWPFDocument) table1.getPart(), table1);
        // 对比表格样式
        CjCompareJobResultEntity result = compareTableStyle(table1, table2, compareItemsDto);
        if (result != null) {
            result.setTableno(tableNo);
            result.setPageno(tableNo);
            resultList.add(result);
        }

        int i = 0;
        while (i < Math.max(table1.getRows().size(), table2.getRows().size())) {

            List<CjCompareJobResultEntity> rowResult = compareRow(table1, table2, i,
                compareItemsDto);
            for (CjCompareJobResultEntity resultEntity : rowResult) {
                resultEntity.setTableno(tableNo);
                resultEntity.setPageno(tableNo);
                resultEntity.setRowno(i);
                resultList.add(resultEntity);
            }
            i++;
        }

        return resultList;
    }

    /**
     * @param table1:
     * @param table2:
     * @param rowNo:
     * @param compareItemsDto: 2023-06-14 wxm添加参数：支持对比项自定义
     * @description: 按行进行比对
     * @return: java.util.List<com.topscomm.mis.cbb.file.compare.cj.pojo.CjCompareJobResultEntity>
     * @author: zhanglongfei
     * @date: 2023/2/23 14:49
     * @modify:
     */
    private List<CjCompareJobResultEntity> compareRow(XWPFTable table1, XWPFTable table2,
        int rowNo, CompareItemsDto compareItemsDto) {
        List<CjCompareJobResultEntity> resultList = new ArrayList<>();
        if (table1.getRows().size() <= rowNo) {
            // 行数不一样，在最后补充缺失的行数
            CjCompareJobResultEntity resultEntity = createNewResultEntity();
            resultEntity.setDoccontent2("存在该行");
            resultEntity.setDoccontent1("缺少该行");
            resultEntity.setDifftype(CjSystemConst.CjCompareJobResultDiffType.Add);
            table1.addRow(table2.getRow(rowNo));
            resultList.add(resultEntity);
        } else if (table2.getRows().size() <= rowNo) {
            // 行数不一样，在最后补充缺失的行数
            CjCompareJobResultEntity resultEntity = createNewResultEntity();
            resultEntity.setDoccontent1("存在该行");
            resultEntity.setDoccontent2("缺少该行");
            resultEntity.setDifftype(CjSystemConst.CjCompareJobResultDiffType.Del);
            table2.addRow(table1.getRow(rowNo));
            resultList.add(resultEntity);
        } else {
            // 行数相同，进行行样式对比
            CjCompareJobResultEntity result = compareRowStyle(table1.getRow(rowNo),
                table2.getRow(rowNo), compareItemsDto);
            if (result != null) {
                resultList.add(result);
            }
            XWPFTableRow row1 = table1.getRow(rowNo);
            XWPFTableRow row2 = table2.getRow(rowNo);
            int i = 0;
            // 列样式比对
            while (i < Math.max(row1.getTableCells().size(), row2.getTableCells().size())) {
                List<CjCompareJobResultEntity> cellResultList = compareCell(row1, row2, i,
                    compareItemsDto);
                for (CjCompareJobResultEntity resultEntity : cellResultList) {
                    resultEntity.setColumnno(i);
                    resultList.add(resultEntity);
                }
                i++;
            }
        }
        return resultList;
    }

    /**
     * @param row1:
     * @param row2:
     * @param cellNo:
     * @param compareItemsDto: 2023-06-14 wxm添加参数：支持对比项自定义
     * @description: 按列进行比对
     * @return: java.util.List<com.topscomm.mis.cbb.file.compare.cj.pojo.CjCompareJobResultEntity>
     * @author: zhanglongfei
     * @date: 2023/2/23 15:03
     * @modify:
     */
    private List<CjCompareJobResultEntity> compareCell(XWPFTableRow row1, XWPFTableRow row2,
        int cellNo, CompareItemsDto compareItemsDto) {
        List<CjCompareJobResultEntity> resultList = new ArrayList<>();
        if (row1.getTableCells().size() <= cellNo) {
            // 列数不一致，在最后补充缺失的列
            CjCompareJobResultEntity resultEntity = createNewResultEntity();
            resultEntity.setDoccontent2("存在该列");
            resultEntity.setDoccontent1("缺少该列");
            resultEntity.setDifftype(CjSystemConst.CjCompareJobResultDiffType.Add);
            row1.addNewTableCell();
            resultList.add(resultEntity);
        } else if (row2.getTableCells().size() <= cellNo) {
            // 列数不一致，在最后补充缺失的列
            CjCompareJobResultEntity resultEntity = createNewResultEntity();
            resultEntity.setDoccontent1("存在该列");
            resultEntity.setDoccontent2("缺少该列");
            resultEntity.setDifftype(CjSystemConst.CjCompareJobResultDiffType.Del);
            row2.addNewTableCell();
            resultList.add(resultEntity);
        } else {
            // 列数一致，对比列样式
            XWPFTableCell cell1 = row1.getCell(cellNo);
            XWPFTableCell cell2 = row2.getCell(cellNo);
            CjCompareJobResultEntity result = compareCellStyle(cell1, cell2, compareItemsDto);
            if (result != null) {
                resultList.add(result);
            }
            // 对比列内段落
            List<CjCompareJobResultEntity> paragraphResultList = compareCellParagraph(cell1, cell2,
                compareItemsDto);
            if (paragraphResultList.size() > 0) {
                resultList.addAll(paragraphResultList);
            }
        }
        return resultList;
    }

    /**
     * @param cell1:
     * @param cell2:
     * @param compareItemsDto: 2023-06-14 wxm添加参数：支持对比项自定义
     * @description: 比较列中段落信息
     * @return: java.util.List<com.topscomm.mis.cbb.file.compare.cj.pojo.CjCompareJobResultEntity>
     * @author: zhanglongfei
     * @date: 2023/2/23 16:52
     * @modify:
     */
    private List<CjCompareJobResultEntity> compareCellParagraph(XWPFTableCell cell1,
        XWPFTableCell cell2, CompareItemsDto compareItemsDto) {
        List<CjCompareJobResultEntity> resultList = new ArrayList<>();
        int i = 0;
        while (i < Math.max(cell1.getParagraphs().size(), cell2.getParagraphs().size())) {
            if (cell1.getParagraphs().size() <= i) {
                // 列内段落缺失，补充缺失段落
                PoiWordUtil.insertCopyParagraph(cell1, cell2.getParagraphs().get(i));
                CjCompareJobResultEntity resultEntity = createNewResultEntity();
                resultEntity.setParagraphno(i);
                resultEntity.setDifftype(CjSystemConst.CjCompareJobResultDiffType.Add);
                resultEntity.setDoccontent2("存在该段落");
                resultEntity.setDoccontent1("缺少该段落");
                resultList.add(resultEntity);
            } else if (cell2.getParagraphs().size() <= i) {
                // 列内段落缺失，补充缺失段落
                PoiWordUtil.insertCopyParagraph(cell2, cell1.getParagraphs().get(i));
                CjCompareJobResultEntity resultEntity = createNewResultEntity();
                resultEntity.setParagraphno(i);
                resultEntity.setDifftype(CjSystemConst.CjCompareJobResultDiffType.Add);
                resultEntity.setDoccontent1("存在该段落");
                resultEntity.setDoccontent2("缺少该段落");
                resultList.add(resultEntity);
            } else {
                // 列内段落一致，对比段落内容与样式
                if (paragraphCompareHandlers == null || paragraphCompareHandlers.size() == 0) {
                    resultList.addAll(new DefaultParagraphCompareHandler()
                        .doCompare(cell1.getParagraphArray(i), cell2.getParagraphArray(i), cell1,
                            compareItemsDto));
                } else {
                    for (IParagraphCompareHandler paragraphCompareHandler : paragraphCompareHandlers) {
                        resultList.addAll(paragraphCompareHandler
                            .doCompare(cell1.getParagraphArray(i), cell2.getParagraphArray(i),
                                cell1, compareItemsDto));
                    }
                }

            }
            i++;
        }
        return resultList;
    }

    /**
     * @param cell1:
     * @param cell2:
     * @param compareItemsDto: 2023-06-14 wxm添加参数：支持对比项自定义
     * @description: 列样式比对
     * @return: com.topscomm.mis.cbb.file.compare.cj.pojo.CjCompareJobResultEntity
     * @author: zhanglongfei
     * @date: 2023/2/23 16:19
     * @modify:
     */
    private CjCompareJobResultEntity compareCellStyle(XWPFTableCell cell1, XWPFTableCell cell2,
        CompareItemsDto compareItemsDto) {
        List<String> diffContent1 = new ArrayList<>();
        List<String> diffContent2 = new ArrayList<>();

        // 对比表格样式为空
        if (compareItemsDto.getCompareTableStyleDto() == null) {
            return null;
        }

        CompareTableStyleDto compareTableStyleDto = compareItemsDto.getCompareTableStyleDto();
        // 开启列宽对比且有差异
        if (Boolean.TRUE.equals(compareTableStyleDto.getColWidth()) && cell1.getWidth() != cell2
            .getWidth()) {
            diffContent1.add("[列宽度]为：" + cell1.getWidth());
            diffContent2.add("[列宽度]为：" + cell2.getWidth());
        }
        String cell1Color = "";
        try {
            cell1Color = cell1.getColor();
        } catch (Exception e) {

        }
        String cell2Color = "";
        try {
            cell2Color = cell2.getColor();
        } catch (Exception e) {

        }
        // 开启列颜色对比且有差异
//        if (Boolean.TRUE.equals(compareTableStyleDto.getColColor()) && !toString(cell1.getColor())
//            .equals(toString(cell2.getColor()))) {
        if (Boolean.TRUE.equals(compareTableStyleDto.getColColor()) && !toString(cell1Color).equals(toString(cell2Color))) {
            diffContent1.add("[列颜色]为：" + cell1Color);
            diffContent2.add("[列颜色]为：" + cell2Color);
        }
        // 若开启列水平对齐对比且有差异
        if (Boolean.TRUE.equals(compareTableStyleDto.getColAlign())) {
            String align1 =
                cell1.getVerticalAlignment() == null ? "" : cell1.getVerticalAlignment().name();
            String align2 =
                cell2.getVerticalAlignment() == null ? "" : cell2.getVerticalAlignment().name();
            if (!align1.equals(align2)) {
                diffContent1.add("[水平对齐]为：" + align1);
                diffContent2.add("[水平对齐]为：" + align2);
            }
        }

        return getCjCompareJobResultEntity(diffContent1, diffContent2,
            CjSystemConst.CjCompareJobResultDiffType.StyleDiff);
    }

    /**
     * @param row1:
     * @param row2:
     * @param compareItemsDto: 2023-06-14 wxm添加参数：支持对比项自定义
     * @description: 表格行样式比对
     * @return: com.topscomm.mis.cbb.file.compare.cj.pojo.CjCompareJobResultEntity
     * @author: zhanglongfei
     * @date: 2023/2/23 14:39
     * @modify:
     */
    private CjCompareJobResultEntity compareRowStyle(XWPFTableRow row1, XWPFTableRow row2,
        CompareItemsDto compareItemsDto) {
        List<String> diffContent1 = new ArrayList<>();
        List<String> diffContent2 = new ArrayList<>();

        // 样式对比为空或行样式对比为空
        if (compareItemsDto.getCompareTableStyleDto() == null) {
            return null;
        }

        // 开启行样式对比且样式有差异则记录
        if (Boolean.TRUE
            .equals(compareItemsDto.getCompareTableStyleDto().getRowHeight())
            && row1.getHeight() != row2.getHeight()) {
            diffContent1.add("[行高度]为：" + row1.getHeight());
            diffContent2.add("[行高度]为：" + row2.getHeight());
        }

        return getCjCompareJobResultEntity(diffContent1, diffContent2,
            CjSystemConst.CjCompareJobResultDiffType.StyleDiff);
    }

    /**
     * @param table1:
     * @param table2:
     * @param compareItemsDto: 2023-06-14 wxm添加参数：支持对比项自定义
     * @description: 检查表格级别的样式
     * @return: com.topscomm.mis.cbb.file.compare.cj.pojo.CjCompareJobResultEntity
     * @author: zhanglongfei
     * @date: 2023/2/23 14:39
     * @modify:
     */
    private CjCompareJobResultEntity compareTableStyle(XWPFTable table1, XWPFTable table2,
        CompareItemsDto compareItemsDto) {
        List<String> diffContent1 = new ArrayList<>();
        List<String> diffContent2 = new ArrayList<>();

        // 样式对比为空或表格样式对比为空
        if (compareItemsDto.getCompareTableStyleDto() == null) {
            return null;
        }
        // 表格样式对比为true且样式不一致则记录
        if (Boolean.TRUE
            .equals(compareItemsDto.getCompareTableStyleDto().getTableWidth())
            && table1.getWidth() != table2.getWidth()) {
            diffContent1.add("[表格宽度]为：" + table1.getWidth());
            diffContent2.add("[表格宽度]为：" + table2.getWidth());
        }
        return getCjCompareJobResultEntity(diffContent1, diffContent2,
            CjSystemConst.CjCompareJobResultDiffType.StyleDiff);
    }
}
